<template>

  <div style="width:30vw;height:70vh">
<!--    <h1>echarts渲染</h1>-->
    <div

        ref="graph"

        style="width:100vw;height:100vh"

    >
    </div>

  </div>

</template>

<script>
import * as echarts from 'echarts/dist/echarts';
import lodash from 'lodash';
import axios from "axios";
import {LOGINURL} from "@/assets/js/HrefLocation"
function transformData(input) {
  return input.map(item => ({
    source: String(item.hydroNode1.id),
    target: String(item.hydroNode2.id),
    relation: item.relation
  }));
}
function convertRelations(relations) {
  // 创建一个映射，用于将数字ID转换为节点名称
  const idToNodeMap = {};
  let currentNodeNumber = 1; // 从1开始编号，因为示例中没有0节点

  // 遍历关系数组，为每个独特的ID创建一个节点名称（如果尚未创建）
  relations.forEach(relation => {
    if (!(relation.source in idToNodeMap)) {
      idToNodeMap[relation.source] =`${relation.source}`
    }
    if (!(relation.target in idToNodeMap)) {

      idToNodeMap[relation.target] = `${relation.target}`;
      // 注意：如果source和target的范围不重叠，上面的递增可能不会产生连续的Node编号。
      // 在这个例子中，我们假设它们是连续的或至少不重叠，因此每次遇到新ID时都递增。
      // 在实际应用中，你可能需要根据具体情况调整这一点。
    }
    if (!(relation.relation in idToNodeMap)) {
      idToNodeMap[relation.relation] =`${relation.relation}`
    }
  });

  // 创建新的关系数组，使用节点名称而不是ID

  const convertedRelations = relations.map(relation => {
    return {
      source: idToNodeMap[relation.source],
      target: idToNodeMap[relation.target],
      relation:idToNodeMap[relation.relation]
      // 注意：这里我们没有包含'type'和'relation'属性，
      // 因为ECharts的graph类型通常不需要它们来渲染边。
      // 如果你需要在图表中使用这些信息，你可以将它们作为额外的属性添加到对象中。
    };
  });

  return convertedRelations;
}
export default {

  data() {

    return {

      // 绘制知识图谱的节点数据

      echartsData: [],

      nodesRelation: [],

      echartsNode: [],

      // 防止出现多个echarts初始化的情况

      myChart: '',

      options: {},

    }

  },

  mounted() {

    this.searchGraph()

  },

  methods: {



    async searchGraph() {
      var result = "";
      try {
        const res = await axios.get("/hkgapi/hydro/getAllRelationFromNeo4j", {});
        result = (res.data);  // 请求完成后更新 result
        console.log(result);  // 在数据获取完成后打印 result
      } catch (error) {
          var status=error.response.status;
          var errorMsg;
          if(status===401){
            errorMsg="请登录后查看"
          }else if(status===500){
            errorMsg="服务器错误"
          }
        this.$alert("请求失败："+errorMsg,"错误",{
          showClose: false,
          confirmButtonText:"跳转登录"
        }).then(()=>{
          localStorage.removeItem("token")
          location.href=LOGINURL;
        })
        console.error("请求失败:", error);
      }
        var me = {records: []}
        me.records = result;

        for (let i = 0; i < me.records.length; i++) {
          // console.log(me.records[i]._fields)
          // 获取节点和关系
          let nodeN = me.records[i].hydroNode1; // 旅行者节点
          let nodeM = me.records[i].hydroNode2; // 提瓦特节点
          let relationship = me.records[i].relation; // 游玩关系
          this.echartsData.push({

            id: nodeN.id,
            name: nodeN.name,


          });

          this.echartsData.push({

            id: nodeM.id,
            name: nodeM.name,


          });

          this.nodesRelation.push({

            source:  nodeN.id,
            target: nodeM.id,
            relation: relationship

          });

        }

        //删除arr中的重复对象

        var arrId = [];

        var legend = [];

        for (var item of this.echartsData) {

          legend.push({name: item.category})

          if (arrId.indexOf(item.name) == -1) {

            arrId.push(item.name)

            this.echartsNode.push(item);

          }

        }

        this.category = Array.from(new Set(legend))



        // me.closeLoading(false);

        var options = {}

        options = {

          tooltip: {//弹窗

            show: true,

            // enterable: true,//鼠标是否可进入提示框浮层中

            // formatter: formatterHover,//修改鼠标悬停显示的内容

          },

          legend: {

            type: 'scroll',

            orient: 'vertical',

            left: 10,

            top: 20,

            bottom: 20,

            data: this.category

          },
          series: [

            {

              categories: this.category,

              type: "graph",

              layout: "force",

              zoom: 0.6,

              symbolSize: 60,

              // 节点是否可以拖动

              draggable: true,

              roam: true,

              hoverAnimation: false,

              legendHoverLink: false,

              nodeScaleRatio: 0.6, //鼠标漫游缩放时节点的相应缩放比例，当设为0时节点不随着鼠标的缩放而缩放

              focusNodeAdjacency: false, //是否在鼠标移到节点上的时候突出显示节点以及节点的边和邻接节点。

              // categories: categories,

              itemStyle: {

                color: "#67A3FF",

              },

              edgeSymbol: ["", "arrow"],

              // edgeSymbolSize: [80, 10],

              edgeLabel: {

                normal: {

                  show: true,

                  textStyle: {

                    fontSize: 12,

                  },
                  //决定边的信息
                  formatter (x) {
                    return x.data.relation;  // 显示边的name和value
                  },

                },

              },

              label: {

                normal: {

                  show: true,

                  textStyle: {

                    fontSize: 12,

                  },

                  color: "#f6f6f6",

                  textBorderColor: '#67A3FF',

                  textBorderWidth: '1.3',

                  // 多字换行

                  formatter: function (params) {

                    // console.log(params);

                    var newParamsName = "";

                    var paramsNameNumber = params.name.length;

                    var provideNumber = 7; //一行显示几个字

                    var rowNumber = Math.ceil(paramsNameNumber / provideNumber);

                    if (paramsNameNumber > provideNumber) {

                      for (var p = 0; p < rowNumber; p++) {

                        var tempStr = "";

                        var start = p * provideNumber;

                        var end = start + provideNumber;

                        if (p == rowNumber - 1) {

                          tempStr = params.name.substring(start, paramsNameNumber);

                        } else {

                          tempStr = params.name.substring(start, end) + "\n\n";

                        }

                        newParamsName += tempStr;

                      }

                    } else {

                      newParamsName = params.name;

                    }

                    return newParamsName;

                  },

                },

              },

              force: {
                repulsion: 200, // 节点之间的斥力因子。支持数组表达斥力范围，值越大斥力越大。
                gravity: 0.01, // 节点受到的向中心的引力因子。该值越大节点越往中心点靠拢。
                edgeLength: 400, // 边的两个节点之间的距离，这个距离也会受 repulsion影响 。值越大则长度越长
                layoutAnimation: true, // 因为力引导布局会在多次迭代后才会稳定，这个参数决定是否显示布局的迭代动画
                // 在浏览器端节点数据较多（>100）的时候不建议关闭，布局过程会造成浏览器假死。
              },
              data: lodash.uniqBy(this.echartsData, item => item.name),
              // links: convertRelations(lodash.uniqBy(this.nodesRelation, item => item.target))
              links: convertRelations(this.nodesRelation)
              // categories: this.categories

            }

          ]

        }
        console.log(convertRelations(this.nodesRelation))

        //节点自定义拖拽不回弹

        this.myChart = echarts.init(this.$refs.graph);

        const chart = this.myChart;

        this.myChart.setOption(options);

        chart.on('mouseup', function (params) {

          var option = chart.getOption();

          option.series[0].data[params.dataIndex].x = params.event.offsetX;

          option.series[0].data[params.dataIndex].y = params.event.offsetY;

          option.series[0].data[params.dataIndex].fixed = true;

          chart.setOption(option);

        });


    },

  }

}

</script>

<style lang='less' scoped>

</style>